﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.RobotJog.CApRJRobotJogFrameLogic
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using EngineeringInternalExtension;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Tecnomatix.Engineering;


namespace DnProcessSimulateCommands.RobotJog;

public class CApRJRobotJogFrameLogic
{
  private TxFrame _workingFrame;
  private TxFrame _temporaryFrame;
  private CApRJRobotJogFrameInfo _oppositeToSelfFrameInfo;
  private CApRJRobotJogFrameInfo _selfFrameInfo;
  private CApRJRobotJogFrameInfo _tcpfWithBaseOrientationFrameInfo;
  private List<CApRJRobotJogFrameInfo> _systemFrameInfos;
  private List<CApRJRobotJogWorkToolInfo> _toolboxPhysicalWorkToolInfos;
  private List<TxFrame> _toolboxVirtualFrames;
  private ITxLocatableObject _movingObject;
  private TxFrame _frameOfReference;
  private bool _blockUpdateOnFrameInfoChange;
  private TxRobot _robot;
  private IEnumerable<TxFrame> _allFrames;

  public event Action<TxFrame> FrameOfReferenceChanged;

  public event Action<TxFrame> FrameOfReferenceLocationChanged;

  public event Action FramesUpdated;

  public CApRJRobotJogFrameLogic(TxRobot robot) => this._robot = robot;

  public bool IsFrameOfReferenceValid { get; set; }

  public FrameType FrameType { get; set; }

  public ITxLocatableObject MovingObject
  {
    get => this._movingObject;
    set
    {
      if (this._movingObject == value)
        return;
      this._allFrames = (IEnumerable<TxFrame>) null;
      this.DeleteFrameList();
      this._movingObject = value;
      this.CreateFrameList();
      if (this._blockUpdateOnFrameInfoChange)
        return;
      this.OnFrameOfReferenceChanged();
      TxApplication.RefreshDisplay();
    }
  }

  public TxFrame FrameOfReference
  {
    get => this._frameOfReference;
    private set => this._frameOfReference = value;
  }

  public IEnumerable<TxFrame> AllFrames
  {
    get
    {
      if (this._allFrames == null)
        this._allFrames = this.CreateSortedAllFramesList();
      return this._allFrames;
    }
  }

  private TxFrame CreateFrame(string name, TxTransformation location, bool hidden)
  {
    TxFrame frame = TxFrameEx.CreateFrame(new TxFrameCreationDataEx(name, location, true));
    if (hidden)
      frame.Blank();
    else
      frame.Color = TxColor.TxColorDarkGreen;
    return frame;
  }

  private void CreateFrameList()
  {
    if (this.MovingObject == null)
      return;
    this.CreateMainFramesList();
    this.CreateSystemFramesList();
    this.CreateToolFramesList();
    this.RegisterEvents();
    this.FrameOfReference = this._selfFrameInfo.Frame;
  }

  private void CreateMainFramesList()
  {
    TxFrame movingObject = this.MovingObject as TxFrame;
    this._selfFrameInfo = new CApRJRobotJogFrameInfo(movingObject);
    this._oppositeToSelfFrameInfo = new CApRJRobotJogFrameInfo(this.FindOppositeFrame(movingObject));
    this._workingFrame = this.CreateFrame(RJRobotJogResources.WorkingFrame, TxApplication.ActiveDocument.WorkingFrame, true);
    if (TxFrame.op_Equality(movingObject, (ITxObject) this._robot.TCPF))
      this._tcpfWithBaseOrientationFrameInfo = new CApRJRobotJogFrameInfo(this.CreateFrame(RJRobotJogResources.TCPFWithBASEOrientation, this.GetTCPFWithBaseOrientation(), true));
    else
      this._tcpfWithBaseOrientationFrameInfo = (CApRJRobotJogFrameInfo) null;
  }

  private TxTransformation GetTCPFWithBaseOrientation()
  {
    return new TxTransformation(this._robot.TCPF.AbsoluteLocation.Translation, this._robot.Baseframe.AbsoluteLocation.RotationRPY_XYZ, (TxTransformation.TxRotationType) 1);
  }

  private void CreateSystemFramesList()
  {
    TxObjectList allSystemFrames = this._robot.GetAllSystemFrames();
    this._systemFrameInfos = new List<CApRJRobotJogFrameInfo>();
    foreach (TxFrame frame in (Collection<ITxObject>) allSystemFrames)
      this._systemFrameInfos.Add(new CApRJRobotJogFrameInfo(frame));
  }

  private void CreateToolFramesList()
  {
    this._toolboxPhysicalWorkToolInfos = new List<CApRJRobotJogWorkToolInfo>();
    this._toolboxVirtualFrames = new List<TxFrame>();
    if (this._robot.Toolbox == null)
      return;
    foreach (TxRobotWorkTool allTool in this._robot.Toolbox.GetAllTools())
    {
      if (allTool.Tool != null)
      {
        if (allTool is TxRobotPhysicalFrameWorkTool)
        {
          TxRobotPhysicalFrameWorkTool physicalFrameWorkTool = allTool as TxRobotPhysicalFrameWorkTool;
          if (TxFrame.op_Inequality(physicalFrameWorkTool.TCPF, (ITxObject) null))
          {
            TxFrame frame = this.CreateFrame(allTool.Name, allTool.GetTCPFAbsoluteLocation(), true);
            this._toolboxPhysicalWorkToolInfos.Add(new CApRJRobotJogWorkToolInfo(physicalFrameWorkTool.TCPF, frame));
          }
        }
        if (allTool is TxRobotVirtualFrameWorkTool)
        {
          TxRobotVirtualFrameWorkTool virtualFrameWorkTool = allTool as TxRobotVirtualFrameWorkTool;
          if (TxTransformation.op_Inequality(((TxRobotWorkTool) virtualFrameWorkTool).GetTCPFAbsoluteLocation(), (TxTransformation) null))
            this._toolboxVirtualFrames.Add(this.CreateFrame(((TxRobotWorkTool) virtualFrameWorkTool).Name, ((TxRobotWorkTool) virtualFrameWorkTool).GetTCPFAbsoluteLocation(), true));
        }
      }
    }
  }

  private IEnumerable<TxFrame> CreateSortedAllFramesList()
  {
    List<TxFrame> source = new List<TxFrame>((IEnumerable<TxFrame>) this._systemFrameInfos.ConvertAll<TxFrame>((Converter<CApRJRobotJogFrameInfo, TxFrame>) (x => x.Frame)));
    source.AddRange((IEnumerable<TxFrame>) this._toolboxPhysicalWorkToolInfos.ConvertAll<TxFrame>((Converter<CApRJRobotJogWorkToolInfo, TxFrame>) (x => x.DisplayFrame)));
    source.AddRange((IEnumerable<TxFrame>) this._toolboxVirtualFrames);
    if (TxFrame.op_Inequality(this._temporaryFrame, (ITxObject) null))
      source.Add(this._temporaryFrame);
    List<TxFrame> sortedAllFramesList = new List<TxFrame>()
    {
      this._selfFrameInfo.Frame,
      this._workingFrame,
      this._oppositeToSelfFrameInfo.Frame
    };
    if (this._tcpfWithBaseOrientationFrameInfo != null)
      sortedAllFramesList.Add(this._tcpfWithBaseOrientationFrameInfo.Frame);
    sortedAllFramesList.AddRange((IEnumerable<TxFrame>) source.OrderBy<TxFrame, string>((Func<TxFrame, string>) (x => x.Name)));
    return (IEnumerable<TxFrame>) sortedAllFramesList;
  }

  private TxFrame FindOppositeFrame(TxFrame frame)
  {
    return frame.Equals((object) this._robot.TCPF) ? this._robot.Baseframe : this._robot.TCPF;
  }

  private void DeleteFrameList()
  {
    if (this.MovingObject != null)
    {
      this._workingFrame.Delete();
      if (this._tcpfWithBaseOrientationFrameInfo != null)
        this._tcpfWithBaseOrientationFrameInfo.Frame.Delete();
      if (TxFrame.op_Inequality(this._temporaryFrame, (ITxObject) null))
      {
        this._temporaryFrame.Delete();
        this._temporaryFrame = (TxFrame) null;
      }
      this.FrameOfReference = (TxFrame) null;
    }
    if (this._toolboxPhysicalWorkToolInfos != null)
    {
      foreach (CApRJRobotJogWorkToolInfo physicalWorkToolInfo in this._toolboxPhysicalWorkToolInfos)
        physicalWorkToolInfo.DisplayFrame.Delete();
      this._toolboxPhysicalWorkToolInfos.Clear();
    }
    if (this._toolboxVirtualFrames != null)
    {
      foreach (TxFrame toolboxVirtualFrame in this._toolboxVirtualFrames)
        toolboxVirtualFrame.Delete();
      this._toolboxVirtualFrames.Clear();
    }
    this.UnregisterEvents();
  }

  public void Delete()
  {
    this.DeleteFrameList();
    TxApplication.RefreshDisplay();
  }

  private void OnFrameOfReferenceChanged()
  {
    this.FrameType = FrameType.None;
    if (TxFrame.op_Inequality(this.FrameOfReference, (ITxObject) null))
    {
      if (this._selfFrameInfo != null && TxFrame.op_Equality(this.FrameOfReference, (ITxObject) this._selfFrameInfo.Frame))
        this.FrameType = FrameType.Self;
      else if (this._tcpfWithBaseOrientationFrameInfo != null && TxFrame.op_Equality(this.FrameOfReference, (ITxObject) this._tcpfWithBaseOrientationFrameInfo.Frame))
        this.FrameType = FrameType.TCPFWithBaseOrientation;
    }
    if (this.FrameOfReferenceChanged == null)
      return;
    this.FrameOfReferenceChanged(this.FrameOfReference);
  }

  private void OnFrameOfReferenceLocationChanged()
  {
    if (this.FrameOfReferenceLocationChanged == null)
      return;
    this.FrameOfReferenceLocationChanged(this.FrameOfReference);
  }

  public void FrameChanged(string name, TxTransformation location)
  {
    this.IsFrameOfReferenceValid = true;
    TxFrame txFrame = !TxFrame.op_Inequality(this.FrameOfReference, (ITxObject) null) || !this.FrameOfReference.IsValid() || !(this.FrameOfReference.Name == name) || !this.FrameOfReference.AbsoluteLocation.Equals((object) location) ? this.FindFrameInList(name, location) : this.FrameOfReference;
    if (TxFrame.op_Equality(txFrame, (ITxObject) null))
    {
      if (TxFrame.op_Inequality(this._temporaryFrame, (ITxObject) null))
      {
        this._temporaryFrame.Delete();
        this._temporaryFrame = (TxFrame) null;
      }
      txFrame = this.FindFrame(name, location);
      if (TxFrame.op_Equality(txFrame, (ITxObject) null))
      {
        txFrame = this.CreateFrame(name, location, false);
        this._temporaryFrame = txFrame;
      }
    }
    else
    {
      if (TxFrame.op_Inequality(this._temporaryFrame, (ITxObject) null) && !txFrame.Equals((object) this._temporaryFrame))
      {
        this._temporaryFrame.Delete();
        this._temporaryFrame = (TxFrame) null;
      }
      if (this._tcpfWithBaseOrientationFrameInfo != null && TxFrame.op_Equality(this._tcpfWithBaseOrientationFrameInfo.Frame, (ITxObject) txFrame))
        this._tcpfWithBaseOrientationFrameInfo.Frame.AbsoluteLocation = this.GetTCPFWithBaseOrientation();
    }
    if (this._blockUpdateOnFrameInfoChange)
      return;
    this.FrameOfReference = txFrame;
    this.OnFrameOfReferenceChanged();
    if (TxUndoTransactionManagerEx.IsObserverRunningInUndoExecution())
      return;
    TxApplication.RefreshDisplay();
  }

  public void AbsoluteLocationChanged()
  {
    if (this._tcpfWithBaseOrientationFrameInfo == null || !TxFrame.op_Equality(this._tcpfWithBaseOrientationFrameInfo.Frame, (ITxObject) this.FrameOfReference))
      return;
    this._tcpfWithBaseOrientationFrameInfo.Frame.AbsoluteLocation = this.GetTCPFWithBaseOrientation();
  }

  private void OnFramesUpdated(TxFrame frame)
  {
    this._allFrames = (IEnumerable<TxFrame>) null;
    if (this.FramesUpdated == null)
      return;
    if (TxFrame.op_Inequality(frame, (ITxObject) null) && TxFrame.op_Inequality(frame, (ITxObject) this.FrameOfReference))
      this._blockUpdateOnFrameInfoChange = true;
    this.FramesUpdated();
    this._blockUpdateOnFrameInfoChange = false;
  }

  private void RegisterEvents()
  {
    if (this._systemFrameInfos != null)
    {
      foreach (CApRJRobotJogFrameInfo systemFrameInfo in this._systemFrameInfos)
      {
        TxFrame frame = systemFrameInfo.Frame;
        frame.Deleted += new TxObject_DeletedEventHandler(this.systemFrame_Deleted);
        frame.NameChanged += new TxObject_NameChangedEventHandler(this.systemFrame_NameChanged);
        frame.AbsoluteLocationChanged += new TxLocatableObject_AbsoluteLocationChangedEventHandler(this.systemFrame_AbsoluteLocationChanged);
      }
    }
    if (this._toolboxPhysicalWorkToolInfos == null)
      return;
    foreach (CApRJRobotJogWorkToolInfo physicalWorkToolInfo in this._toolboxPhysicalWorkToolInfos)
      physicalWorkToolInfo.Frame.Deleted += new TxObject_DeletedEventHandler(this.toolboxFrame_Deleted);
  }

  private void UnregisterEvents()
  {
    if (this._systemFrameInfos != null)
    {
      foreach (CApRJRobotJogFrameInfo systemFrameInfo in this._systemFrameInfos)
      {
        TxFrame frame = systemFrameInfo.Frame;
        frame.Deleted -= new TxObject_DeletedEventHandler(this.systemFrame_Deleted);
        frame.NameChanged -= new TxObject_NameChangedEventHandler(this.systemFrame_NameChanged);
        frame.AbsoluteLocationChanged -= new TxLocatableObject_AbsoluteLocationChangedEventHandler(this.systemFrame_AbsoluteLocationChanged);
      }
    }
    if (this._toolboxPhysicalWorkToolInfos == null)
      return;
    foreach (CApRJRobotJogWorkToolInfo physicalWorkToolInfo in this._toolboxPhysicalWorkToolInfos)
      physicalWorkToolInfo.Frame.Deleted -= new TxObject_DeletedEventHandler(this.toolboxFrame_Deleted);
  }

  private void systemFrame_NameChanged(object sender, TxObject_NameChangedEventArgs args)
  {
    this.OnFramesUpdated(sender as TxFrame);
  }

  private void systemFrame_AbsoluteLocationChanged(
    object sender,
    TxLocatableObject_AbsoluteLocationChangedEventArgs args)
  {
    this._allFrames = (IEnumerable<TxFrame>) null;
    if (!TxFrame.op_Equality(sender as TxFrame, (ITxObject) this.FrameOfReference))
      return;
    this.OnFrameOfReferenceLocationChanged();
  }

  private void systemFrame_Deleted(object sender, TxObject_DeletedEventArgs args)
  {
    TxFrame frame = sender as TxFrame;
    if (!TxFrame.op_Inequality(frame, (ITxObject) null))
      return;
    if (TxFrame.op_Equality(frame, (ITxObject) this.FrameOfReference))
      this.FrameOfReference = this._selfFrameInfo.Frame;
    frame.Deleted -= new TxObject_DeletedEventHandler(this.systemFrame_Deleted);
    frame.NameChanged -= new TxObject_NameChangedEventHandler(this.systemFrame_NameChanged);
    frame.AbsoluteLocationChanged -= new TxLocatableObject_AbsoluteLocationChangedEventHandler(this.systemFrame_AbsoluteLocationChanged);
    this._systemFrameInfos.Remove(this._systemFrameInfos.Where<CApRJRobotJogFrameInfo>((Func<CApRJRobotJogFrameInfo, bool>) (fr => TxFrame.op_Equality(fr.Frame, (ITxObject) frame))).FirstOrDefault<CApRJRobotJogFrameInfo>());
    this.OnFramesUpdated(frame);
  }

  private void toolboxFrame_Deleted(object sender, TxObject_DeletedEventArgs args)
  {
    TxFrame frame = sender as TxFrame;
    if (!TxFrame.op_Inequality(frame, (ITxObject) null))
      return;
    CApRJRobotJogWorkToolInfo robotJogWorkToolInfo = this._toolboxPhysicalWorkToolInfos.Where<CApRJRobotJogWorkToolInfo>((Func<CApRJRobotJogWorkToolInfo, bool>) (wt => TxFrame.op_Equality(wt.Frame, (ITxObject) frame))).FirstOrDefault<CApRJRobotJogWorkToolInfo>();
    if (robotJogWorkToolInfo == null)
      return;
    if (TxFrame.op_Equality(robotJogWorkToolInfo.DisplayFrame, (ITxObject) this.FrameOfReference))
      this.FrameOfReference = this._selfFrameInfo.Frame;
    this._toolboxPhysicalWorkToolInfos.Remove(robotJogWorkToolInfo);
    robotJogWorkToolInfo.DisplayFrame.Delete();
    this.OnFramesUpdated(frame);
  }

  private TxFrame FindFrame(string name, TxTransformation location)
  {
    foreach (TxFrame allDescendant in (Collection<ITxObject>) TxApplication.ActiveDocument.PhysicalRoot.GetAllDescendants((ITxTypeFilter) new TxTypeFilter(typeof (TxFrame))))
    {
      if (this.FramesMatch(allDescendant, name, location))
        return allDescendant;
    }
    return (TxFrame) null;
  }

  private TxFrame FindFrameInList(string name, TxTransformation location)
  {
    foreach (TxFrame allFrame in this.AllFrames)
    {
      if (this.FramesMatch(allFrame, name, location))
        return allFrame;
    }
    return (TxFrame) null;
  }

  private bool FramesMatch(TxFrame frame, string name, TxTransformation location)
  {
    bool flag = frame.Name == name && frame.AbsoluteLocation.Equals((object) location);
    if (!flag && frame.Name == name)
    {
      flag = this._selfFrameInfo.IsMatchTo(frame.Name, location) || this._oppositeToSelfFrameInfo.IsMatchTo(frame.Name, location) || this._tcpfWithBaseOrientationFrameInfo != null && this._tcpfWithBaseOrientationFrameInfo.IsMatchTo(frame.Name, location);
      if (!flag)
      {
        foreach (CApRJRobotJogFrameInfo systemFrameInfo in this._systemFrameInfos)
        {
          if (systemFrameInfo.IsMatchTo(frame.Name, location))
          {
            flag = true;
            break;
          }
        }
      }
    }
    return flag;
  }
}
